﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace _21_异步委托
{
    public delegate int AddDelegate(int a, int b, out string result);
    internal class Program
    {
        public static int Add(int a, int b, out string result)
        {
            Thread.Sleep(5000);//休眠5000MS等于1秒，模拟耗时操作。Thread.Sleep:休眠当前所在线程
            int value = a + b;
            result = string.Format("{0}+{1}={2}", a, b, value);
            return value;
        }

        static void Main(string[] args)
        {
            //实例化委托
            AddDelegate addDelegate = new AddDelegate(Add);
            //提示开始调用计算
            Console.WriteLine("[{0}] 开始调用计算", DateTime.Now);
            //调用异步委托
            //参数一:委托的第一个参数
            //参数二:委托的第二个参数
            //参数三:out参数
            //参数四:回调函数(稍后讲解)
            //参数五:回调函数的参数
            //方法返回值:IAsyncResult(委托的异步结果,提供查询异步操作的状态和获取异步操作的结果的方法)
            IAsyncResult iar = addDelegate.BeginInvoke(1, 2, out string result,null,null);
            //模拟执行其他操作
            Console.Write("正在执行其他操作");
            for (int i = 0; i < 5; i++)
            {
                Thread.Sleep(1000);
                Console.Write(".");
            }
            Console.WriteLine();
            //使用AsyncWaitHandle的WaitOne()方法等待异步操作完成，
            iar.AsyncWaitHandle.WaitOne();//阻塞当前线程等待异步操作完成，(异步操作完成的时候会取消对当前线程的阻塞)
            //获取异步委托的结果,如果异步操作完成,则返回委托的返回值否则将阻塞当前线程直到异步操作完成。
            int value = addDelegate.EndInvoke(out result, iar);
            //打印表达式
            Console.WriteLine("[{0}] 表达式:{1}", DateTime.Now, result);
            //获取同步委托的结果
            Console.WriteLine("[{0}] 计算结果:{1}", DateTime.Now, value);

            Console.ReadKey();
        }
    }
}
